home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
frasrc19.zip
/
LSYSAF.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-09-24
|
11KB
|
480 lines
; LSYSAF.ASM: assembler support routines for optimized L-System code
; (floating-point version)
; Nicholas Wilt, 7/93.
.MODEL MEDIUM,C
lsys_turtlestatef STRUC
counter DB ?
angle DB ?
reverse DB ?
stackoflow DB ?
maxangle DB ?
dmaxangle DB ?
curcolor DB ?
dummy DB ?
ssize DT ?
realangle DT ?
xpos DT ?
ypos DT ?
xmin DT ?
ymin DT ?
xmax DT ?
ymax DT ?
aspect DT ?
num DD ?
lsys_turtlestatef ENDS
EXTRN overflow:WORD
EXTRN draw_line:FAR
EXTRN FPUsincos:FAR
EXTRN cpu:WORD
EXTRN boxy:TBYTE
sins_f equ boxy
coss_f equ boxy + 500 ; 50 * 10 bytes
.CODE
DECANGLE MACRO
LOCAL @1
dec al
jge @1
mov al,[bx.dmaxangle]
@1: mov [bx.angle],al
ENDM
INCANGLE MACRO
LOCAL @1
inc al
cmp al,[bx.maxangle]
jne @1
xor ax,ax
@1: mov [bx.angle],al
ENDM
PUBLIC lsysf_doplus
lsysf_doplus PROC lsyscmd:ptr
mov bx,lsyscmd
mov al,[bx.angle]
cmp [bx.reverse],0
jnz PlusIncAngle
DECANGLE
ret
PlusIncAngle:
INCANGLE
ret
lsysf_doplus ENDP
PUBLIC lsysf_dominus
lsysf_dominus PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
mov al,[bx.angle]
cmp [bx.reverse],0
jnz MinusDecAngle
INCANGLE
ret
MinusDecAngle:
DECANGLE
ret
lsysf_dominus ENDP
PUBLIC lsysf_doplus_pow2
lsysf_doplus_pow2 PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
mov al,[bx.angle]
cmp [bx.reverse],0
jnz Plus2IncAngle
dec al
and al,[bx.dmaxangle]
mov [bx.angle],al
ret
Plus2IncAngle:
inc al
and al,[bx.dmaxangle]
mov [bx.angle],al
ret
lsysf_doplus_pow2 ENDP
PUBLIC lsysf_dominus_pow2
lsysf_dominus_pow2 PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
mov al,[bx.angle]
cmp [bx.reverse],0
jz Minus2IncAngle
dec al
and al,[bx.dmaxangle]
mov [bx.angle],al
ret
Minus2IncAngle:
inc al
and al,[bx.dmaxangle]
mov [bx.angle],al
ret
lsysf_dominus_pow2 ENDP
PUBLIC lsysf_dopipe_pow2
lsysf_dopipe_pow2 PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
xor ax,ax
mov al,[bx.maxangle]
shr ax,1
xor dx,dx
mov dl,[bx.angle]
add ax,dx
and al,[bx.dmaxangle]
mov [bx.angle],al
ret
lsysf_dopipe_pow2 ENDP
PUBLIC lsysf_dobang
lsysf_dobang PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
mov al,[bx.reverse] ; reverse = ! reverse;
dec al ; -1 if was 0; 0 if was 1
neg al ; 1 if was 0; 0 if was 1
mov [bx.reverse],al ;
ret
lsysf_dobang ENDP
PUBLIC lsysf_doat
lsysf_doat PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
fld tbyte ptr [bx.num] ; Get N.
; FPU stk: N xpos ypos size aspect
fmulp st(3),st ; Multiply size by it.
ret
lsysf_doat ENDP
.386
LSYS_SINCOS MACRO OFFS
LOCAL UseSinCos, Done
cmp cpu,386 ; If CPU >= 386, we can use fsincos.
jge UseSinCos ;
; Otherwise we use FPUsincos.
sub sp,50+24 ; Save enough room for entire state
; plus parameter to sin or cos
fstp tbyte ptr [bp-OFFS-10] ; Save state
fstp tbyte ptr [bp-OFFS-20] ;
fstp tbyte ptr [bp-OFFS-30] ;
fstp tbyte ptr [bp-OFFS-40] ;
fld st ; realangle remains on FPU stack
fstp tbyte ptr [bp-OFFS-50] ;
fstp qword ptr [bp-OFFS-50-8] ; Store as parameter to FPUsincos
lea ax,[bp-OFFS-50-16] ; Push pointer to cosine
push ax ;
lea ax,[bp-OFFS-50-24] ; Push pointer to sine
push ax ;
lea ax,[bp-OFFS-50-8] ; Push pointer to parameter
push ax ;
call FPUsincos ; Call it.
add sp,6 ; Restore stack
fld tbyte ptr [bp-OFFS-50] ; Restore state
fld tbyte ptr [bp-OFFS-40] ;
fld tbyte ptr [bp-OFFS-30] ;
fld tbyte ptr [bp-OFFS-20] ;
fld tbyte ptr [bp-OFFS-10] ;
fld qword ptr [bp-OFFS-50-24] ; Get sine
fld qword ptr [bp-OFFS-50-16] ; Get cosine
add sp,50+24 ; Restore stack
jmp short Done ;
UseSinCos:
fld st(4) ; Get angle
fsincos ; c s xpos ypos size aspect realangle
Done:
ENDM
PUBLIC lsysf_dosizedm
lsysf_dosizedm PROC lsyscmd:ptr
LSYS_SINCOS 0 ; Get sine and cosine of angle.
mov bx,lsyscmd ; Get pointer to structure
fmul st,st(5) ; c*aspect s xpos ypos size aspect
fmul st,st(4) ; c*size*aspect s xpos ypos size aspect
faddp st(2),st ; s xpos ypos size aspect
fmul st,st(3) ; s*size xpos ypos size aspect
faddp st(2),st ; xpos ypos size aspect
push ax ; Allocate a local for FP status word
fld [bx.xmin] ; Compare xpos to xmin
fcomp ;
fstsw [bp-2] ; Store status word
mov ax,[bp-2] ;
sahf ;
jb SizeDM1 ; Jump if ST > xmin
fld st ;
fstp [bx.xmin] ;
jmp short SizeDM2 ;
SizeDM1:
fld [bx.xmax] ; Compare to xmax
fcomp ;
fstsw [bp-2] ; Store status word
mov ax,[bp-2] ;
sahf ;
ja SizeDM2 ; Jump if ST < xmax
fld st ;
fstp [bx.xmax] ;
SizeDM2:
fxch ; Swap xpos and ypos
fld [bx.ymin] ; Compare ypos to ymin
fcomp ;
fstsw [bp-2] ; Store status word
mov ax,[bp-2] ;
sahf ;
jb SizeDM3 ; Jump if ST > ymin
fld st ;
fstp [bx.ymin] ;
jmp short SizeDM4 ;
SizeDM3:
fld [bx.ymax] ; Compare ypos to ymax
fcomp ;
fstsw [bp-2] ;
mov ax,[bp-2] ;
sahf ;
ja SizeDM4 ;
fld st ;
fstp [bx.ymax] ;
SizeDM4:
fxch ; Swap xpos and ypos back
pop ax ; Deallocate local for FPU status word
ret ; Done.
lsysf_dosizedm ENDP
PUBLIC lsysf_dosizegf
lsysf_dosizegf PROC USES SI,lsyscmd:ptr
mov si,lsyscmd ;
xor bx,bx ; BX <- angle * sizeof(long double)
mov bl,[si.angle] ;
shl bx,1 ;
mov ax,bx ;
shl ax,1 ;
shl ax,1 ;
add bx,ax ;
fld st(2) ; size xpos ypos size aspect
fld coss_f[bx] ; size*cmd->coss[cmd->angle]
fmul ;
faddp st(1),st ; xpos ypos size aspect
fld st(2) ; size xpos ypos size aspect
fld sins_f[bx] ; size*cmd->sins[cmd->angle]
fmul ;
faddp st(2),st ; xpos ypos size aspect
push ax ; Allocate a local for FPU status word
fld [si.xmin] ; Compare xpos to xmin
fcomp ;
fstsw [bp-4] ; Store status word
mov ax,[bp-4] ;
sahf ;
jb SizeGF1 ; Jump if ST > xmin
fld st ;
fstp [si.xmin] ;
jmp short SizeGF2 ;
SizeGF1:
fld [si.xmax] ; Compare to xmax
fcomp ;
fstsw [bp-4] ; Store status word
mov ax,[bp-4] ;
sahf ;
ja SizeGF2 ; Jump if ST < xmax
fld st ;
fstp [si.xmax] ;
SizeGF2:
fxch ; Swap xpos and ypos
fld [si.ymin] ; Compare ypos to ymin
fcomp ;
fstsw [bp-4] ; Store status word
mov ax,[bp-4] ;
sahf ;
jb SizeGF3 ; Jump if ST > ymin
fld st ;
fstp [si.ymin] ;
jmp short SizeGF4 ;
SizeGF3:
fld [si.ymax] ; Compare ypos to ymax
fcomp ;
fstsw [bp-4] ;
mov ax,[bp-4] ;
sahf ;
ja SizeGF4 ;
fld st ;
fstp [si.ymax] ;
SizeGF4:
fxch ; Swap xpos and ypos back
pop ax ; Deallocate local for FPU status word
ret
lsysf_dosizegf ENDP
PUBLIC lsysf_dodrawg
lsysf_dodrawg PROC USES SI,lsyscmd:ptr
mov si,lsyscmd ; Get pointer to structure
xor bx,bx ; Get angle offset
mov bl,[si.angle] ;
mov al,10 ;
mul bl ;
xchg ax,bx ;
fld coss_f[bx] ; xpos += cmd->size * cmd->coss[cmd->angle]
fmul st,st(3) ;
fadd ;
fld sins_f[bx] ; ypos += cmd->size * cmd->sins[cmd->angle]
fmul st,st(3) ;
faddp st(2),st ;
ret ;
lsysf_dodrawg ENDP
PUBLIC lsysf_dodrawd
lsysf_dodrawd PROC lsyscmd:PTR
mov bx,lsyscmd ; Get pointer to structure
xor ax,ax ; Push last parm to draw_line
mov al,[bx.curcolor]
push ax ;
sub sp,8 ; Allocate the rest of draw_line's parms
fist word ptr [bp-10] ; Store xpos
fxch ; Store ypos
fist word ptr [bp-8] ;
fxch ;
LSYS_SINCOS 10 ; c s xpos ypos size aspect
fmul st,st(5) ; c*aspect s xpos ypos size aspect
fmul st,st(4) ; size*c*aspect s xpos ypos size aspect
faddp st(2),st ; s xpos ypos size aspect
fmul st,st(3) ; s*size xpos ypos size aspect
faddp st(2),st ; xpos ypos size aspect
fist word ptr [bp-6] ; Store xpos
fxch ; Store ypos
fist word ptr [bp-4] ;
fxch ;
call far ptr draw_line ;
add sp,10 ; Remove parameters
ret ;
lsysf_dodrawd ENDP
PUBLIC lsysf_dodrawm
lsysf_dodrawm PROC lsyscmd:ptr
LSYS_SINCOS 0 ;
fmul st,st(5) ; c*aspect s xpos ypos size aspect
fmul st,st(4) ; size*c*aspect s xpos ypos size aspect
faddp st(2),st ; s xpos ypos size aspect
fmul st,st(3) ; s*size xpos ypos size aspect
faddp st(2),st ; xpos ypos size aspect
ret ;
lsysf_dodrawm ENDP
PUBLIC lsysf_dodrawf
lsysf_dodrawf PROC USES SI, lsyscmd:ptr
mov si,lsyscmd ; Get pointer to structure
xor ax,ax ; Push curcolor for draw_line
mov al,[si.curcolor] ;
push ax ;
sub sp,8 ; Allocate the rest of the draw_line call
fist word ptr [bp-12] ; Store xpos in draw_line parms
fxch ; Store ypos in draw_line parms
fist word ptr [bp-10] ;
fxch ;
xor bx,bx ; BX <- offset into cos/sin arrays
mov bl,[si.angle] ;
mov al,10 ;
mul bl ;
xchg ax,bx ;
fld st(2) ; xpos += size*cmd->coss[cmd->angle]
fld coss_f[bx] ;
fmul
fadd ;
fist word ptr [bp-8] ; Store new xpos in draw_line parms
fld st(2) ; ypos += size*cmd->sins[cmd->angle]
fld sins_f[bx] ;
fmul ;
faddp st(2),st ;
fxch ; Store new ypos in draw_line parms
fist word ptr [bp-6] ;
fxch ;
call far ptr draw_line ; Call the line-drawing routine
add sp,10 ; Deallocate the stuff we pushed
ret ;
lsysf_dodrawf ENDP
PUBLIC lsysf_doslash
lsysf_doslash PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
fld tbyte ptr [bx.num]
cmp [bx.reverse],0
jnz DoSlashDec
faddp st(5),st
ret
DoSlashDec:
fsubp st(5),st
ret
lsysf_doslash ENDP
PUBLIC lsysf_dobslash
lsysf_dobslash PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer
fld tbyte ptr [bx.num]
cmp [bx.reverse],0
jz DoBSlashDec
faddp st(5),st
ret
DoBSlashDec:
fsubp st(5),st
ret
lsysf_dobslash ENDP
PUBLIC lsys_prepfpu
lsys_prepfpu PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer to structure
fld [bx.realangle] ; Load: xpos ypos size aspect realangle
fld [bx.aspect] ;
fld [bx.ssize] ;
fld [bx.ypos] ;
fld [bx.xpos] ;
ret ; Return.
lsys_prepfpu ENDP
PUBLIC lsys_donefpu
lsys_donefpu PROC lsyscmd:ptr
mov bx,lsyscmd ; Get pointer to structure
fstp [bx.xpos] ; Save: xpos ypos size aspect realangle
fstp [bx.ypos] ;
fstp [bx.ssize] ;
fstp [bx.aspect] ;
fstp [bx.realangle] ;
ret
lsys_donefpu ENDP
END